/*     */ package com.zimbra.cs.servlet;
/*     */ 
/*     */ import com.zimbra.common.localconfig.KnownKey;
/*     */ import com.zimbra.common.localconfig.LC;
/*     */ import com.zimbra.common.util.ByteUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.LruMap;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import java.io.File;
/*     */ import java.io.FileInputStream;
/*     */ import java.io.FileOutputStream;
/*     */ import java.io.FilenameFilter;
/*     */ import java.io.IOException;
/*     */ import java.io.InputStream;
/*     */ import java.io.InputStreamReader;
/*     */ import java.io.OutputStream;
/*     */ import java.io.OutputStreamWriter;
/*     */ import java.io.PrintWriter;
/*     */ import java.io.Reader;
/*     */ import java.io.Writer;
/*     */ import java.text.SimpleDateFormat;
/*     */ import java.util.Date;
/*     */ import java.util.Map;
/*     */ import java.util.zip.GZIPOutputStream;
/*     */ import javax.servlet.ServletConfig;
/*     */ import javax.servlet.ServletContext;
/*     */ import javax.servlet.ServletException;
/*     */ import javax.servlet.ServletRequest;
/*     */ import javax.servlet.ServletResponse;
/*     */ import javax.servlet.http.HttpServletResponse;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public abstract class DiskCacheServlet
/*     */   extends ZimbraServlet
/*     */ {
/*     */   private Map<String, File> cache;
/*     */   private String cacheDirName;
/*     */   private File cacheDir;
/*     */   private int cacheSize;
/*     */   protected String cacheKeyPrefix;
/*     */   protected static final String EXT_COMPRESSED = ".gz";
/*     */   protected static final String P_CACHE_DIR = "resource-cache-dir";
/*     */   protected static final String P_CACHE_SIZE = "resource-cache-size";
/*     */   
/*     */   protected DiskCacheServlet(String cacheDirName)
/*     */   {
/*  64 */     this.cacheDirName = cacheDirName;
/*     */   }
/*     */   
/*     */   public void init(ServletConfig config) throws ServletException
/*     */   {
/*  69 */     super.init(config);
/*  70 */     String contextName = getServletContext().getServletContextName();
/*  71 */     if (contextName != null) {
/*  72 */       this.cacheKeyPrefix = contextName.replaceAll("[^a-zA-Z0-9_]", "");
/*     */     } else {
/*  74 */       this.cacheKeyPrefix = "_";
/*     */     }
/*  76 */     createCache();
/*  77 */     createCacheDir();
/*     */   }
/*     */   
/*     */   public void service(ServletRequest req, ServletResponse resp)
/*     */     throws IOException, ServletException
/*     */   {
/*  83 */     if (flushCache(req)) {
/*  84 */       return;
/*     */     }
/*  86 */     super.service(req, resp);
/*     */   }
/*     */   
/*     */   protected boolean flushCache(ServletRequest req) {
/*  90 */     Boolean flushCache = (Boolean)req.getAttribute("flushCache");
/*  91 */     if ((flushCache != null) && (flushCache.booleanValue())) {
/*  92 */       if (ZimbraLog.misc.isDebugEnabled()) {
/*  93 */         ZimbraLog.misc.debug("flushing " + getClass().getName() + " cache");
/*     */       }
/*  95 */       boolean deleteFiles = true;
/*  96 */       clearCache(deleteFiles);
/*  97 */       return true;
/*     */     }
/*  99 */     return false;
/*     */   }
/*     */   
/*     */ 
/*     */   protected int getCacheSize()
/*     */   {
/* 105 */     return this.cacheSize;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   protected String getCacheDirName()
/*     */   {
/* 115 */     return this.cacheDirName;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   protected File getCacheDir()
/*     */   {
/* 122 */     return this.cacheDir;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   protected String getCacheKey(String cacheId)
/*     */   {
/* 129 */     return this.cacheKeyPrefix + '-' + ByteUtil.getMD5Digest(cacheId.getBytes(), false);
/*     */   }
/*     */   
/*     */   protected File createCacheFile(String cacheId)
/*     */     throws IOException
/*     */   {
/* 135 */     return createCacheFile(cacheId, null);
/*     */   }
/*     */   
/*     */   protected File createCacheFile(String cacheId, String ext) throws IOException {
/* 139 */     String cacheKey = getCacheKey(cacheId);
/*     */     
/* 141 */     return new File(this.cacheDir.getAbsolutePath() + '/' + cacheKey + '-' + Thread.currentThread().getId() + '.' + (ext == null ? "tmp" : ext));
/*     */   }
/*     */   
/*     */   protected synchronized File getCacheFile(String cacheId)
/*     */   {
/* 146 */     return (File)this.cache.get(getCacheKey(cacheId));
/*     */   }
/*     */   
/*     */   protected synchronized void putCacheFile(String cacheId, File file) {
/* 150 */     String cacheKey = getCacheKey(cacheId);
/* 151 */     File oldFile = (File)this.cache.get(cacheKey);
/*     */     
/* 153 */     if (oldFile != null) {
/* 154 */       oldFile.delete();
/*     */     }
/* 156 */     this.cache.put(cacheKey, file);
/*     */   }
/*     */   
/*     */   protected synchronized void clearCache(boolean deleteFiles) {
/* 160 */     if (deleteFiles) {
/* 161 */       for (File file : this.cache.values()) {
/* 162 */         ZimbraLog.misc.debug("deleting file %s", new Object[] { file.getAbsolutePath() });
/* 163 */         file.delete();
/*     */         
/* 165 */         File gzfile = new File(file.getParentFile(), file.getName() + ".gz");
/* 166 */         if (gzfile.exists()) {
/* 167 */           gzfile.delete();
/*     */         }
/*     */       }
/*     */     }
/* 171 */     this.cache.clear();
/*     */   }
/*     */   
/*     */   protected void processRemovedFile(String cacheId, File file) {
/* 175 */     file.delete();
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   protected void createCache()
/*     */   {
/* 182 */     this.cacheSize = LC.zimbra_disk_cache_servlet_size.intValue();
/* 183 */     String value = getServletConfig().getInitParameter("resource-cache-size");
/* 184 */     if (value != null) {
/*     */       try {
/* 186 */         this.cacheSize = Integer.parseInt(value.trim());
/*     */       }
/*     */       catch (NumberFormatException e) {}
/*     */     }
/*     */     
/*     */ 
/* 192 */     this.cache = new LruMap(this.cacheSize)
/*     */     {
/*     */       protected void willRemove(String cacheId, File file) {
/* 195 */         DiskCacheServlet.this.processRemovedFile(cacheId, file);
/*     */       }
/*     */     };
/*     */   }
/*     */   
/*     */   protected synchronized void createCacheDir() {
/* 201 */     if (this.cacheDir == null) {
/* 202 */       String subDirName = "latest";
/*     */       
/* 204 */       if (this.cacheDirName != null) {
/* 205 */         subDirName = this.cacheDirName + '/' + subDirName;
/*     */       }
/* 207 */       subDirName = subDirName.replace('/', File.separatorChar);
/* 208 */       this.cacheDir = new File(getTempDir(), subDirName);
/* 209 */       if (this.cacheDir.exists()) {
/* 210 */         if (LC.zimbra_disk_cache_servlet_flush.booleanValue()) {
/* 211 */           Date date = new Date(this.cacheDir.lastModified());
/* 212 */           String timestamp = new SimpleDateFormat("yyyy-MM-dd-HHmmss").format(date);
/* 213 */           File parentDir = this.cacheDir.getParentFile();
/* 214 */           File backupDir = new File(parentDir, timestamp);
/*     */           
/* 216 */           this.cacheDir.renameTo(backupDir);
/* 217 */           this.cacheDir = new File(getTempDir(), subDirName);
/*     */         } else {
/* 219 */           for (String file : this.cacheDir.list()) {
/* 220 */             int idx = file.lastIndexOf("-");
/*     */             
/* 222 */             if (idx != -1) {
/* 223 */               String cacheKey = file.substring(0, idx);
/*     */               
/* 225 */               this.cache.put(cacheKey, new File(this.cacheDir.getAbsolutePath() + File.separatorChar + file));
/*     */             }
/*     */           }
/*     */         }
/*     */       }
/*     */       
/* 231 */       this.cacheDir.mkdirs();
/* 232 */       cleanupOldCacheDirs();
/*     */     }
/*     */   }
/*     */   
/*     */   protected void cleanupOldCacheDirs() {
/* 237 */     Thread thread = new Thread()
/*     */     {
/*     */       public void run() {
/* 240 */         File dir = DiskCacheServlet.this.getCacheDir().getParentFile();
/* 241 */         File[] files = dir.listFiles(new DiskCacheServlet.CacheDirFilter());
/*     */         
/* 243 */         for (File file : files) {
/* 244 */           if (file.isDirectory())
/* 245 */             delete(file);
/*     */         }
/*     */       }
/*     */       
/*     */       public void delete(File dir) {
/* 250 */         File[] files = dir.listFiles();
/* 251 */         for (File file : files) {
/* 252 */           if (file.isDirectory()) {
/* 253 */             delete(file);
/*     */           }
/*     */           else {
/* 256 */             file.delete();
/*     */           }
/*     */         }
/* 259 */         dir.delete();
/*     */       }
/* 261 */     };
/* 262 */     thread.start();
/*     */   }
/*     */   
/*     */ 
/*     */   protected File getTempDir()
/*     */   {
/* 268 */     File tempDir = null;
/* 269 */     String cacheDirname = getServletConfig().getInitParameter("resource-cache-dir");
/*     */     
/* 271 */     if (cacheDirname != null)
/*     */     {
/* 273 */       String webappDirname = getServletContext().getRealPath("/").replace(File.separatorChar, '/');
/*     */       
/* 275 */       cacheDirname = cacheDirname.replaceAll("\\$\\{webapp\\}", webappDirname).replace('/', File.separatorChar).trim();
/*     */       
/* 277 */       tempDir = new File(cacheDirname);
/*     */     } else {
/* 279 */       tempDir = new File(LC.zimbra_tmp_directory.value() + "/diskcache");
/*     */     }
/* 281 */     tempDir.mkdirs();
/* 282 */     return tempDir;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   protected File compress(File src)
/*     */     throws IOException
/*     */   {
/* 290 */     File dest = new File(src.getParentFile(), src.getName() + ".gz");
/* 291 */     return compress(src, dest);
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */   protected File compress(File src, File dest)
/*     */     throws IOException
/*     */   {
/* 299 */     GZIPOutputStream out = new GZIPOutputStream(new FileOutputStream(dest));
/*     */     
/* 301 */     copy(src, out);
/* 302 */     out.finish();
/* 303 */     out.close();
/*     */     
/* 305 */     return dest;
/*     */   }
/*     */   
/*     */   protected void copy(File src, HttpServletResponse resp, boolean compress)
/*     */     throws IOException
/*     */   {
/* 311 */     if (compress) {
/*     */       try {
/* 313 */         resp.setHeader("Content-Encoding", "gzip");
/*     */       } catch (IllegalStateException e) {
/* 315 */         compress = false;
/*     */       }
/*     */     }
/*     */     try {
/* 319 */       OutputStream out = resp.getOutputStream();
/* 320 */       if (compress) {
/* 321 */         File gzSrc = new File(src.getParentFile(), src.getName() + ".gz");
/*     */         
/* 323 */         if (gzSrc.exists()) {
/* 324 */           src = gzSrc;
/* 325 */           compress = false;
/*     */         } else {
/* 327 */           out = new GZIPOutputStream(out);
/*     */         }
/*     */       }
/* 330 */       copy(src, out);
/* 331 */       if (compress) {
/* 332 */         ((GZIPOutputStream)out).finish();
/*     */       }
/*     */     } catch (IllegalStateException e) {
/* 335 */       PrintWriter out = resp.getWriter();
/* 336 */       copy(src, out);
/*     */     }
/*     */   }
/*     */   
/*     */   protected void copy(String src, HttpServletResponse resp, boolean compress)
/*     */     throws IOException
/*     */   {
/* 343 */     if (compress) {
/*     */       try {
/* 345 */         resp.setHeader("Content-Encoding", "gzip");
/*     */       } catch (IllegalStateException e) {
/* 347 */         compress = false;
/*     */       }
/*     */     }
/*     */     try {
/* 351 */       OutputStream out = resp.getOutputStream();
/* 352 */       if (compress) {
/* 353 */         out = new GZIPOutputStream(out);
/*     */       }
/* 355 */       out.write(src.getBytes("UTF-8"));
/* 356 */       if (compress) {
/* 357 */         ((GZIPOutputStream)out).finish();
/*     */       }
/*     */     } catch (IllegalStateException e) {
/* 360 */       PrintWriter out = resp.getWriter();
/* 361 */       out.write(src);
/*     */     }
/*     */   }
/*     */   
/*     */   protected void copy(File src, OutputStream dest) throws IOException
/*     */   {
/* 367 */     byte[] buffer = new byte['က'];
/*     */     
/* 369 */     InputStream in = new FileInputStream(src);
/*     */     int count;
/* 371 */     while ((count = in.read(buffer)) != -1) {
/* 372 */       dest.write(buffer, 0, count);
/*     */     }
/* 374 */     dest.flush();
/* 375 */     in.close();
/*     */   }
/*     */   
/*     */   protected void copy(File src, Writer dest) throws IOException
/*     */   {
/* 380 */     char[] buffer = new char['က'];
/*     */     
/* 382 */     Reader in = new InputStreamReader(new FileInputStream(src), "UTF-8");
/*     */     int count;
/* 384 */     while ((count = in.read(buffer)) != -1) {
/* 385 */       dest.write(buffer, 0, count);
/*     */     }
/* 387 */     dest.flush();
/* 388 */     in.close();
/*     */   }
/*     */   
/*     */   protected void copy(String src, File dest) throws IOException
/*     */   {
/* 393 */     OutputStream out = new FileOutputStream(dest);
/* 394 */     copy(src, out);
/* 395 */     out.close();
/*     */   }
/*     */   
/*     */   protected void copy(String src, OutputStream dest) throws IOException
/*     */   {
/* 400 */     Writer out = new OutputStreamWriter(dest, "UTF-8");
/* 401 */     out.write(src);
/* 402 */     out.flush();
/*     */   }
/*     */   
/*     */   protected void copy(String src, Writer dest) throws IOException
/*     */   {
/* 407 */     dest.write(src);
/* 408 */     dest.flush();
/*     */   }
/*     */   
/*     */   static class CacheDirFilter implements FilenameFilter
/*     */   {
/*     */     public boolean accept(File dir, String name) {
/* 414 */       return !name.equals("latest");
/*     */     }
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/servlet/DiskCacheServlet.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */